package service

import (
	"github.com/cn-ygf/go-admin/internal/modular/system/dao"
	"github.com/cn-ygf/go-admin/internal/modular/system/model"
	"github.com/cn-ygf/go-admin/internal/modular/system/vo"
)

var (
	DeptService = new(deptService)
)

// deptService 部门管理
type deptService struct {
}

// GetByID 根据Id查询
func (s *deptService) GetByID(deptId int64) (*model.SysDept, error) {
	return dao.SysDept.Where(dao.SysDept.DeptID.Eq(deptId)).First()
}

// GetList 获取部门列表
func (s *deptService) GetList(deptName string, status string) ([]*model.SysDept, error) {
	u := dao.SysDept
	m := u.Where()
	if deptName != "" {
		m = m.Where(u.DeptName.Like("%" + deptName + "%"))
	}
	if status != "" {
		m = m.Where(u.Status.Eq(status))
	}
	return m.Find()
}

// Update 修改部门
func (s *deptService) Update(req *vo.EditDeptReq) error {
	u := dao.SysDept
	_, err := u.Where(u.DeptID.Eq(req.DeptID)).Updates(map[string]any{
		u.DeptName.ColumnName().String():  req.DeptName,
		u.ParentID.ColumnName().String():  req.ParentID,
		u.Ancestors.ColumnName().String(): req.Ancestors,
		u.OrderNum.ColumnName().String():  req.OrderNum,
		u.Leader.ColumnName().String():    req.Leader,
		u.Phone.ColumnName().String():     req.Phone,
		u.Email.ColumnName().String():     req.Email,
		u.Status.ColumnName().String():    req.Status,
		u.UpdateBy.ColumnName().String():  req.UpdateBy,
	})
	if err != nil {
		systemLog.Errorln(err.Error())
		return ServerError
	}
	return nil
}

// Add 添加部门
func (s *deptService) Add(req *vo.AddDeptReq) error {
	u := dao.SysDept
	newDept := &model.SysDept{
		ParentID:  req.ParentID,
		Ancestors: req.Ancestors,
		DeptName:  req.DeptName,
		OrderNum:  req.OrderNum,
		Leader:    req.Leader,
		Phone:     req.Phone,
		Email:     req.Email,
		Status:    req.Status,
		CreateBy:  req.CreateBy,
	}
	err := u.Create(newDept)
	if err != nil {
		systemLog.Errorln(err.Error())
		return ServerError
	}
	return nil
}

// Delete 删除部门
func (s *deptService) Delete(id int64) error {
	_, err := dao.SysDept.Where(dao.SysDept.DeptID.Eq(id)).Delete()
	return err
}

// HasChildByDeptId 是否存在下级部门
func (s *deptService) HasChildByDeptId(id int64) bool {
	l, err := dao.SysDept.Where(dao.SysDept.ParentID.Eq(id)).Count()
	if err != nil {
		systemLog.Errorln(err.Error())
		return true
	}
	return l > 0
}

// CheckDeptExistUser 是否存在关联用户
func (s *deptService) CheckDeptExistUser(id int64) bool {
	l, err := dao.SysUser.Where(dao.SysUser.DeptID.Eq(id)).Count()
	if err != nil {
		systemLog.Errorln(err.Error())
		return true
	}
	return l > 0
}

// GetChild 获取一个部门的所有子部门id
// 不包括自身
func (s *deptService) GetChild(deptId int64) ([]int64, error) {
	deptList, err := dao.SysDept.Where(dao.SysDept.Status.Eq("0")).Find()
	if err != nil {
		systemLog.Errorln(err.Error())
		return nil, ServerError
	}
	r := make([]int64, 0)
	s.findDeptChild(deptId, deptList, &r)
	return r, nil
}

func (s *deptService) findDeptChild(mid int64, depts []*model.SysDept, r *[]int64) {
	for _, item := range depts {
		if item.ParentID == mid {
			*r = append(*r, item.DeptID)
			s.findDeptChild(item.DeptID, depts, r)
		}
	}
}

// GetMaps 获取字典数据
// map[部门id]部门名称
func (s *deptService) GetMaps() (map[int64]string, error) {
	r := make(map[int64]string)
	list, err := dao.SysDept.Where(dao.SysDept.Status.Eq("0")).Find()
	if err != nil {
		systemLog.Errorln(err.Error())
		return nil, ServerError
	}
	for _, item := range list {
		r[item.DeptID] = item.DeptName
	}
	return r, nil
}

func (s *deptService) GetMapsEx() (map[int64]*model.SysDept, error) {
	r := make(map[int64]*model.SysDept)
	list, err := dao.SysDept.Where(dao.SysDept.Status.Eq("0")).Find()
	if err != nil {
		systemLog.Errorln(err.Error())
		return nil, ServerError
	}
	for _, item := range list {
		r[item.DeptID] = item
	}
	return r, nil
}

// GetIdsByRoleId 根据角色id获取部门ids
func (s *deptService) GetIdsByRoleId(roleId int64) ([]int64, error) {
	list, err := dao.SysRoleDept.Where(dao.SysRoleDept.RoleID.Eq(roleId)).Find()
	if err != nil {
		systemLog.Errorln(err.Error())
		return nil, ServerError
	}
	r := make([]int64, 0)
	for _, item := range list {
		r = append(r, item.DeptID)
	}
	return r, nil
}

// SelectTree 查询部门树
func (s *deptService) SelectTree() ([]*vo.DeptTreeSelect, error) {
	deptList, err := dao.SysDept.Where(dao.SysDept.Status.Eq("0")).Find()
	if err != nil {
		systemLog.Errorln(err.Error())
		return nil, ServerError
	}
	roots := make([]*vo.DeptTreeSelect, 0)
	for _, dept := range deptList {
		if dept.ParentID == 0 {
			root := &vo.DeptTreeSelect{
				Id:       dept.DeptID,
				Label:    dept.DeptName,
				Children: nil,
			}
			s.findChildren(deptList, root)
			roots = append(roots, root)
		}
	}
	if len(roots) < 1 {
		systemLog.Errorln("未找到根部门")
		return nil, ServerError
	}

	return roots, nil
}

func (s *deptService) findChildren(list []*model.SysDept, dept *vo.DeptTreeSelect) {
	dept.Children = make([]*vo.DeptTreeSelect, 0)
	for _, item := range list {
		if item.ParentID == dept.Id {
			child := &vo.DeptTreeSelect{
				Id:       item.DeptID,
				Label:    item.DeptName,
				Children: nil,
			}
			dept.Children = append(dept.Children, child)
			s.findChildren(list, child)
		}
	}
}

// CheckDeptNameUnique 检查部门名称是否已存在
func (s *deptService) CheckDeptNameUnique(deptId int64, deptName string) bool {
	if deptId == 0 {
		count, err := dao.SysDept.Where(dao.SysDept.DeptName.Eq(deptName)).Count()
		if err != nil {
			systemLog.Errorln(err.Error())
			return true
		}
		return count < 1
	}
	dept, err := s.GetByID(deptId)
	if err != nil {
		systemLog.Errorln(err.Error())
		return true
	}
	if dept.DeptName == deptName {
		return true
	}
	count, err := dao.SysDept.Where(dao.SysDept.DeptName.Eq(deptName)).Count()
	if err != nil {
		systemLog.Errorln(err.Error())
		return true
	}
	return count < 1
}
